package com.tianji.learning.service.impl;


import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.Constant;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.ReplyDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.vo.ReplyVO;
import com.tianji.learning.enums.QuestionStatus;

import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.query.ReplyPageQuery;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

import java.util.*;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author yang
 * @since 2024-06-25
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {

    private final IInteractionQuestionService questionService;
    private final UserClient userClient;
    private final RabbitMqHelper mqHelper;

    /**
     * 新增互动回答
     *
     * @param replyDTO
     */
    @Override
    public void addReply(ReplyDTO replyDTO) {

        Long user = UserContext.getUser();
        InteractionReply interactionReply = BeanUtils.toBean(replyDTO, InteractionReply.class);
        interactionReply.setUserId(user);
        save(interactionReply);

        Boolean isAnswer = interactionReply.getAnswerId() == null;


        mqHelper.send(
                MqConstants.Exchange.LEARNING_EXCHANGE,
                MqConstants.Key.WRITE_REPLY,
                user);

        if (isAnswer) {
            // 新增回答
            questionService.lambdaUpdate()
                    .eq(InteractionQuestion::getId, replyDTO.getQuestionId())
                    .setSql(isAnswer, "answer_times = answer_times + 1")
                    .set(InteractionQuestion::getLatestAnswerId, interactionReply.getId())
                    .set(replyDTO.getIsStudent(), InteractionQuestion::getStatus, QuestionStatus.UN_CHECK.getValue())
                    .update();
            return;
        }
        // 新增评论
        this.lambdaUpdate()
                .eq(InteractionReply::getAnswerId, replyDTO.getAnswerId())
                .setSql("reply_times = reply_times + 1")
                .update();
        return;
    }

    /**
     * 修改回答隐藏状态
     *
     * @param id
     * @param hidden
     */
    @Override
    public void updateReplyHidden(Long id, Boolean hidden) {
        //1.健壮性判断
        if (id == null) {
            throw new BadRequestException("id不能为空");
        }
        if (hidden == null) {
            throw new BadRequestException("隐藏状态不能为空");
        }

        InteractionReply one = this.lambdaQuery()
                .eq(InteractionReply::getId, id)
                .one();

        if (one.getAnswerId() == null) {
            //是回复
            this.lambdaUpdate()
                    .eq(InteractionReply::getId, one.getId())
                    .set(InteractionReply::getHidden, hidden)
                    .update();

            this.lambdaUpdate()
                    .eq(InteractionReply::getAnswerId, one.getId())
                    .set(InteractionReply::getHidden, hidden)
                    .update();
            return;
        }
        //是评论
        this.lambdaUpdate()
                .eq(InteractionReply::getId, one.getId())
                .set(InteractionReply::getHidden, hidden)
                .update();

    }

    /**
     * 分页查询互动回答列表(共用)
     *
     * @param query
     * @param isAdmin
     * @return
     */
    @Override
    public PageDTO<ReplyVO> getReplyPage(ReplyPageQuery query, Boolean isAdmin) {
        //1.判断是后端查询还是前端查询
        Page<InteractionReply> page=new Page<>();
        if (isAdmin) {
            //2.健壮性判断
            if (query.getQuestionId() != null || query.getAnswerId() != null) {
                //3.查询回复或者评论
                page = this.lambdaQuery()
                        .eq(query.getQuestionId() != null, InteractionReply::getQuestionId, query.getQuestionId())
                        .eq(query.getAnswerId() != null, InteractionReply::getAnswerId, query.getAnswerId())
                        .page(query.toMpPage(
                                new OrderItem(Constant.DATA_FIELD_NAME_LIKED_TIME,false),
                                new OrderItem(Constant.DATA_FIELD_NAME_CREATE_TIME,false)
                        ));

                List<InteractionReply> records = page.getRecords();
                //4.获取回答者id和被回答者id集合
                Set<Long> userIds = new HashSet<>();
                for (InteractionReply record : records) {
                    userIds.add(record.getUserId());
                    if (record.getTargetUserId() != null) {
                        userIds.add(record.getTargetUserId());
                    }
                }
                //5.根据回答者id集合去拿信息
                List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
                Map<Long, UserDTO> userMap = new HashMap<>();
                for (UserDTO userDTO : userDTOS) {
                    userMap.put(userDTO.getId(), userDTO);
                }

                //6.封装回复vo
                List<ReplyVO> replyVOS = BeanUtils.copyList(records, ReplyVO.class);
                for (InteractionReply record : records) {
                    ReplyVO replyVO = BeanUtils.toBean(record, ReplyVO.class);

                    replyVO.setUserName(userMap.get(record.getUserId()).getName());
                    replyVO.setUserIcon(userMap.get(record.getUserId()).getIcon());

                    if (record.getTargetUserId() != null){
                        UserDTO userDTO = userMap.get(record.getTargetUserId());
                        if (userDTO != null){
                            replyVO.setTargetUserName(userDTO.getName());
                        }
                    }


                    replyVOS.add(replyVO);
                }
                return PageDTO.of(page, ReplyVO.class);
            }
        }
        //2.健壮性判断
        if (query.getQuestionId() != null || query.getAnswerId() != null) {
            //3.查询回复或者评论
            page = this.lambdaQuery()
                    .eq(query.getQuestionId() != null, InteractionReply::getQuestionId, query.getQuestionId())
                    .eq(query.getAnswerId() != null, InteractionReply::getAnswerId, query.getAnswerId())
                    .eq(InteractionReply::getHidden, false)
                    .page(query.toMpPage(
                    new OrderItem(Constant.DATA_FIELD_NAME_LIKED_TIME,false),
                    new OrderItem(Constant.DATA_FIELD_NAME_CREATE_TIME,false)
            ));

            List<InteractionReply> records = page.getRecords();
            //4.获取回答者id和被回答者id集合
            Set<Long> userIds = new HashSet<>();
            for (InteractionReply record : records) {
                if (record.getAnonymity()){
                    continue;
                }
                userIds.add(record.getUserId());
                if (record.getTargetUserId() != null) {
                    userIds.add(record.getTargetUserId());
                }
            }
            //5.根据回答者id集合去拿信息
            List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
            Map<Long, UserDTO> userMap = new HashMap<>();
            for (UserDTO userDTO : userDTOS) {
                userMap.put(userDTO.getId(), userDTO);
            }

            //6.封装回复vo
            List<ReplyVO> replyVOS = BeanUtils.copyList(records, ReplyVO.class);
            for (InteractionReply record : records) {
                ReplyVO replyVO = BeanUtils.toBean(record, ReplyVO.class);

                if (!record.getAnonymity()){
                    replyVO.setUserName(userMap.get(record.getUserId()).getName());
                    replyVO.setUserIcon(userMap.get(record.getUserId()).getIcon());
                }
                if (record.getTargetUserId() != null){
                    UserDTO userDTO = userMap.get(record.getTargetUserId());
                    if (userDTO != null){
                        replyVO.setTargetUserName(userDTO.getName());
                    }
                }

                replyVOS.add(replyVO);
            }
        }
        return PageDTO.of(page, ReplyVO.class);
    }


}

